package server

import (
  "fmt"
  //"github.com/siddontang/go-log/log"
)

func nodeLoginCommand(c *requestContext) error {
  uuid := string(c.args[1])
  nodename := string(c.args[2])
  // ignore c.args[3], c.args[4]

  c.family = dflFamilyMgr.GetFamilyByUUID(uuid)
  if c.family == nil {
    c.resp.writeBulk(respInvalidNode)
    return errInvalidNode
  }
  c.nodeinfo = c.family.GetDevice(nodename)
  if c.nodeinfo == nil {
    var err error
    c.nodeinfo, err = c.family.InsertDevice(c.app.db, nodename)
    if err != nil {
      // TODO
      // return what to client??
      return err
    }
  }

  if c.nodeinfo.isLogin {
    c.resp.writeBulk(respAlreadyLogin)
    return errAlreadyLogin
  }
  c.nodeinfo.On(c)

  // login success
  c.resp.writeBulk([]byte(fmt.Sprintf("login ok %s\r\n", c.family.uuid)))

  // broadcast login info
  broadcastNodeLoginInfo(c)

  return nil
}

func broadcastNodeLoginInfo(c *requestContext) {
  if c.family == nil || c.nodeinfo == nil {
    return
  }
  msg := fmt.Sprintf("nodeinfo ok %s on NULL 0\r\n", c.nodeinfo.name)
  c.family.SendMsgToAll([]byte(msg))
}

func nodeSayCommand(c *requestContext) error {
  if c.family == nil || c.nodeinfo == nil || !c.nodeinfo.isLogin {
    c.resp.writeBulk(respUserNoLogin)
    return errUserNoLogin
  }

  var (
    msgReceiver = string(c.args[1])
    msgContent  = c.args[2]
    msgId       = c.args[3]
    qos         = c.args[4]
  )

  receiver := c.family.GetDevice(msgReceiver)
  if receiver == nil {
    c.resp.writeBulk(respNodeNoLogin)
    return errNodeNoLogin
  }

  msgSend := fmt.Sprintf("node ok %s %s %s %s\r\n", c.nodeinfo.name, msgContent, msgId, qos)
  receiver.req.resp.writeBulk([]byte(msgSend))
  receiver.req.resp.flush()

  return nil
}

func nodeHeartBeat(c *requestContext) error {
  // TODO
  c.resp.writeBulk(respHeartbeat)
  return nil
}

func nodeCommand(c *requestContext) (err error) {
  if len(c.args) != 5 {
    return ErrCmdParams
  }

  subcmd := string(c.args[0])
  switch subcmd {
  case "login":
    err = nodeLoginCommand(c)
  case "say":
    err = nodeSayCommand(c)
  case "heartbeat":
    err = nodeHeartBeat(c)
  default:
    err = ErrCmdParams
  }

  return err
}

func init() {
  register("node", nodeCommand)
}
